﻿#include "FITKAbaMaterial.h"
#include "FITKAbaMaterialDensity.h"
#include "FITKAbaMaterialElastic.h"
#include "FITKAbaMaterialPlastic.h"
#include "FITKAbaMaterialExpansion.h"
#include "FITKAbaMaterialHyperElastic.h"
#include "FITKAbaMaterialDamping.h"
#include "FITKAbaMaterialJohnsonCookDamage.h"


Interface::FITKAbaMaterial::~FITKAbaMaterial()
{
    this->clearBehaviors();
}

bool Interface::FITKAbaMaterial::copy(Core::FITKAbstractDataObject* obj)
{
    FITKAbaMaterial* objMat = dynamic_cast<FITKAbaMaterial*>(obj);
    if (objMat == nullptr)
        return false;
    this->clearBehaviors();
    this->setDataObjectName(objMat->getDataObjectName());
    QList<FITKAbaMaterialBehavior*> objBehaviors = objMat->getMaterialBeahviors();
    for (FITKAbaMaterialBehavior* behavior : objBehaviors)
    {
        auto behaviorType = behavior->getMaterialBehaviorType();
        this->addMaterialBehavior(behaviorType);
        FITKAbaMaterialBehavior* newBehavior = this->getMaterialBehavior(behaviorType);
        switch (behaviorType)
        {
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::None:
            break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Density:
        {
            FITKAbaMaterialDensity* d = dynamic_cast<FITKAbaMaterialDensity*>(behavior);
            FITKAbaMaterialDensity* newd = dynamic_cast<FITKAbaMaterialDensity*>(newBehavior);
            *newd = *d;
        }
            break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Elastic:
        {
            FITKAbaMaterialElastic* d = dynamic_cast<FITKAbaMaterialElastic*>(behavior);
            FITKAbaMaterialElastic* newd = dynamic_cast<FITKAbaMaterialElastic*>(newBehavior);
            *newd = *d;
        }
            break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Plastic:
        {
            FITKAbaMaterialPlastic* d = dynamic_cast<FITKAbaMaterialPlastic*>(behavior);
            FITKAbaMaterialPlastic* newd = dynamic_cast<FITKAbaMaterialPlastic*>(newBehavior);
            *newd = *d;
        }
            break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Expansion:
        {
            FITKAbaMaterialExpansion* d = dynamic_cast<FITKAbaMaterialExpansion*>(behavior);
            FITKAbaMaterialExpansion* newd = dynamic_cast<FITKAbaMaterialExpansion*>(newBehavior);
            *newd = *d;
        }
            break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Hyperelastic:
        {
            FITKAbaMaterialHyperElastic* d = dynamic_cast<FITKAbaMaterialHyperElastic*>(behavior);
            FITKAbaMaterialHyperElastic* newd = dynamic_cast<FITKAbaMaterialHyperElastic*>(newBehavior);
            *newd = *d;
        }
            break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Damping:
        {
            FITKAbaMaterialDamping* d = dynamic_cast<FITKAbaMaterialDamping*>(behavior);
            FITKAbaMaterialDamping* newD = dynamic_cast<FITKAbaMaterialDamping*>(newBehavior);
            *newD = *d;
        }
        break;
        case Interface::FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::JohnsonCookDamage:
        {
            FITKAbaMaterialJohnsonCookDamage* d = dynamic_cast<FITKAbaMaterialJohnsonCookDamage*>(behavior);
            FITKAbaMaterialJohnsonCookDamage* newD = dynamic_cast<FITKAbaMaterialJohnsonCookDamage*>(newBehavior);
            *newD = *d;
        }
        default:
            break;
        }
    }
    return true;
}

bool Interface::FITKAbaMaterial::hasMaterialBehavior(FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType type)
{
    for (FITKAbaMaterialBehavior* behavior : m_materialBehaviors)
    {
        auto behaviorType = behavior->getMaterialBehaviorType();
        if (behaviorType == type)
            return true;
    }
    return false;
}

bool Interface::FITKAbaMaterial::addMaterialBehavior(FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType type)
{
    for (FITKAbaMaterialBehavior* behavior : m_materialBehaviors)
    {
        auto behaviorType = behavior->getMaterialBehaviorType();
        if (behaviorType == type)
            return true;
    }
    FITKAbaMaterialBehavior* behavior{nullptr};
    switch (type) {
    case FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Density:
        behavior = new FITKAbaMaterialDensity();
        break;
    case FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Elastic:
        behavior = new FITKAbaMaterialElastic();
        break;
    case FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Plastic:
        behavior = new FITKAbaMaterialPlastic();
        break;
    case FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Expansion:
        behavior = new FITKAbaMaterialExpansion();
        break;
    case FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Hyperelastic:
        behavior = new FITKAbaMaterialHyperElastic();
        break;
    case FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::Damping:
        behavior = new FITKAbaMaterialDamping();
        break;
    case FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType::JohnsonCookDamage:
        behavior = new FITKAbaMaterialJohnsonCookDamage();
        break;
    default:
        break;
    }
    if (behavior == nullptr)
        return false;
    m_materialBehaviors.append(behavior);
    return true;
}

void Interface::FITKAbaMaterial::removeMaterialBehavior(FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType type)
{
    FITKAbaMaterialBehavior* behavior = this->getMaterialBehavior(type);
    if (behavior == nullptr)
        return;
    m_materialBehaviors.removeOne(behavior);
    delete behavior;
}

QList<Interface::FITKAbaMaterialBehavior *> Interface::FITKAbaMaterial::getMaterialBeahviors() const
{
    return m_materialBehaviors;
}

Interface::FITKAbaMaterialBehavior *Interface::FITKAbaMaterial::getMaterialBehavior(FITKAbaMaterialBehaviorEnum::FITKAbaMaterialBehaviorType type)
{
    for (FITKAbaMaterialBehavior* behavior : m_materialBehaviors)
    {
        auto behaviorType = behavior->getMaterialBehaviorType();
        if (behaviorType == type)
            return behavior;
    }
    return nullptr;
}

void Interface::FITKAbaMaterial::clearBehaviors()
{
    for (FITKAbaMaterialBehavior* behavior : m_materialBehaviors)
        delete behavior;
    m_materialBehaviors.clear();
}
